﻿using System;
using System.Linq;
using System.Collections.Generic;
using SIM.Geo.DA;
using SIM.Geo.BE;
using System.Transactions;

namespace SIM.Geo.BL
{
    public class BLMuestraSondaje
    {
        #region Metodos
        /// <summary>
        /// Método que devuelve una lista de muestra sondaje
        /// </summary>
        /// <returns></returns>
        public List<MuestraSondaje> ListarMuestraSondaje(int codigoSondaje)
        {
            return Accesor.ListarMuestraSondaje(codigoSondaje);
        }
        /// <summary>
        /// Método devuelve lista muestra sondaje por codigo
        /// </summary>
        /// <returns></returns>
        public List<MuestraSondaje> BuscarMuestraSondajePorcodigo(int codigoSondaje, string codigoMuestraSondaje)
        {
            return Accesor.BuscarMuestraSondajePorcodigo(codigoSondaje, codigoMuestraSondaje);
        }

        /// <summary>
        /// Método insertar muestra de sondaje
        /// </summary>
        /// <param name="muestrasondaje"></param>
        /// <returns></returns>
        public string InsertarMuestraSondaje(MuestraSondaje muestrasondaje)
        {
            string result = "Registrado";

            using (TransactionScope transaction = new TransactionScope())
            {

                int EsPermitidoLaDistancia = Accesor.ValidarDistanciaMuestraSondaje(muestrasondaje.CodigoSondaje, muestrasondaje.Hasta, muestrasondaje.CodigoTipoControlCalidad);
                if (EsPermitidoLaDistancia != 0)
                {
                    result = "La muestra ingresado está fuera de rango de la Distancia de Sondaje.";
                    return result;
                }

                int interseccion = Accesor.ValidarInterseccionMuestraSondaje(muestrasondaje.CodigoSondaje, muestrasondaje.CodigoMuestraSondaje, muestrasondaje.Desde, muestrasondaje.Hasta, muestrasondaje.CodigoTipoControlCalidad);
                if (interseccion == 1)
                {
                    result = "Existe intersección entre las muestras. ";
                    return result;
                }


                //string codigoNuevo = this.GenerarCodigoMuestraSondaje();
                //muestrasondaje.CodigoMuestraSondaje = codigoNuevo;
                Accesor.InsertarMuestraSondaje(muestrasondaje);

                //Actualizar Estado de Codigo de Muestra como 2=Asociado
                DACodigoMuestra dacodigoMuestra = new DACodigoMuestra();
                var codigoMuestra = dacodigoMuestra.ObtenerCodigoMuestra(muestrasondaje.CodigoMuestraSondaje);
                if (codigoMuestra != null)
                {
                    codigoMuestra.CodigoEstado = 2; //ASOCIADO
                    dacodigoMuestra.ModificarCodigoMuestra(codigoMuestra);
                }

                transaction.Complete();
                return result;
            }
        }
        /// <summary>
        /// Método insertar muestra de sondaje móvil
        /// </summary>
        /// <param name="muestrasondaje"></param>
        /// <returns></returns>
        public string InsertarMuestraSondajeMovil(MuestraSondaje muestrasondaje)
        {
            //string codigoNuevo = this.GenerarCodigoMuestraSondaje();
            //muestrasondaje.CodigoMuestraSondaje = codigoNuevo;
            return Accesor.InsertarMuestraSondaje(muestrasondaje);
        }
        /// <summary>
        /// Método que modifica muestra de sondaje
        /// </summary>
        /// <param name="muestrasondaje"></param>
        public string ModificarMuestraSondaje(MuestraSondaje muestrasondaje)
        {
            string result = "Registrado";

            int EsPermitidoLaDistancia = Accesor.ValidarDistanciaMuestraSondaje(muestrasondaje.CodigoSondaje, muestrasondaje.Hasta, muestrasondaje.CodigoTipoControlCalidad);
            if (EsPermitidoLaDistancia != 0)
            {
                result = "La muestra ingresado está fuera de rango de la Distancia de Sondaje.";
                return result;
            }

            int interseccion = Accesor.ValidarInterseccionMuestraSondaje(muestrasondaje.CodigoSondaje, muestrasondaje.CodigoMuestraSondaje, muestrasondaje.Desde, muestrasondaje.Hasta, muestrasondaje.CodigoTipoControlCalidad);
            if (interseccion == 1)
            {
                result = "Existe intersección entre las muestras.";
                return result;
            }

            var muestrasondajeEdit = Accesor.ObtenerMuestraSondaje(muestrasondaje.CodigoMuestraSondaje);
            muestrasondajeEdit.Desde = muestrasondaje.Desde;
            muestrasondajeEdit.Hasta = muestrasondaje.Hasta;
            muestrasondajeEdit.CodigoGeologo = muestrasondaje.CodigoGeologo;
            muestrasondajeEdit.CodigoTomadorMuestra = muestrasondaje.CodigoTomadorMuestra;
            muestrasondajeEdit.FechaEnvio = muestrasondaje.FechaEnvio;
            muestrasondajeEdit.Observacion = muestrasondaje.Observacion;
            muestrasondajeEdit.CodigoTipoControlCalidad = muestrasondaje.CodigoTipoControlCalidad;
            muestrasondajeEdit.CodigoMuestraSondajeDuplicado = muestrasondaje.CodigoMuestraSondajeDuplicado;
            Accesor.ModificarMuestraSondaje(muestrasondajeEdit);

            return result;
        }
        /// <summary>
        /// Método que elimina muestra sondaje
        /// </summary>
        /// <param name="codigoMuestraSondaje"></param>
        public void EliminarMuestraSondaje(string codigoMuestraSondaje)
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                var muestrasondaje = Accesor.ObtenerMuestraSondaje(codigoMuestraSondaje);
                Accesor.EliminarMuestraSondaje(muestrasondaje);

                //Actualizar Estado de Codigo de Muestra como 1=GENERADO
                DACodigoMuestra dacodigoMuestra = new DACodigoMuestra();
                var codigoMuestra = dacodigoMuestra.ObtenerCodigoMuestra(muestrasondaje.CodigoMuestraSondaje);
                if (codigoMuestra != null)
                {
                    codigoMuestra.CodigoEstado = 1; //GENERADO
                    dacodigoMuestra.ModificarCodigoMuestra(codigoMuestra);
                }

                transaction.Complete();
            }
        }

        /// <summary>
        /// Método que valida leyes de muestras, los sondajes no esten finalizados
        /// </summary>
        /// <param name="leymuestra"></param>
        public List<MuestraSondajeImportacion> ValidarLeyMuestra(List<MuestraSondajeImportacion> leymuestras)
        {
            List<string> codigoMuestas = leymuestras.Select(x => x.CodigoMuestraSondaje).Distinct().ToList();

            var muestrasSondajes = Accesor.ListarMuestraSondajePorcodigos(codigoMuestas);
            var muestrasCanales = new DAMuestraCanal().ListarMuestraCanalPorcodigos(codigoMuestas);
            var muestrasEspeciales = new DAMuestraEspecial().ListarMuestraEspecialPorcodigos(codigoMuestas);

            List<MuestraSondajeResponse> validados = new List<MuestraSondajeResponse>();
            bool valida = true;
            foreach (var item in leymuestras)
            {
                //Segun el tipo de muestra, valida
                if (item.CodigoMuestraSondaje.Contains(Constantes.TipoSerieCodigoMuestra.SONDAJE) || item.CodigoMuestraSondaje.Contains(Constantes.TipoSerieCodigoMuestra.TALADRO))
                {
                    valida = true;

                    //Muestra de Sondaje
                    var muestra = muestrasSondajes.Where(x => x.CodigoMuestraSondaje == item.CodigoMuestraSondaje).FirstOrDefault();
                    if (muestra != null)
                    {
                        var sondaje = new DASondaje().ObtenerSondaje(muestra.CodigoSondaje);
                        if (sondaje == null)
                        {
                            item.Validacion = "Sondaje no encontrado.";
                            valida = false;
                        }
                        else
                        {
                            if (sondaje.Estado == 2)
                            {
                                item.Validacion = "Sondaje con estado finalizado.";
                                valida = false;
                            }
                            else
                            {
                                #region Validacion margen de error
                                //Valida los rangos de error permitidos
                                if (!string.IsNullOrEmpty(muestra.CodigoMuestraSondajeDuplicado))
                                {
                                    if (muestra.CodigoTipoControlCalidad == 2) //Tipo 2=Duplicada: No es necesario validar
                                    {
                                        var tipoControlCalidad = new DATipoControlCalidad().ObtenerTipoControlCalidad(muestra.CodigoTipoControlCalidad);
                                        var muestraAnterior = new DAMuestraSondaje().ObtenerMuestraSondaje(muestra.CodigoMuestraSondajeDuplicado);

                                        //Compara con la muestra actual
                                        if (item.ValorAg > muestraAnterior.ValorAg + tipoControlCalidad.ErrorPermitidoAg)
                                        {
                                            item.Validacion = item.Validacion + " El ValorAg excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorCu > muestraAnterior.ValorCu + tipoControlCalidad.ErrorPermitidoCu)
                                        {
                                            item.Validacion = item.Validacion + " El ValorCu excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorPb > muestraAnterior.ValorPb + tipoControlCalidad.ErrorPermitidoPb)
                                        {
                                            item.Validacion = item.Validacion + " El ValorPb excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorZn > muestraAnterior.ValorZn + tipoControlCalidad.ErrorPermitidoZn)
                                        {
                                            item.Validacion = item.Validacion + " El ValorZn excede al margen de error establecido.";
                                            valida = false;
                                        }
                                    }
                                }
                                #endregion
                            }
                        }

                    }
                    else
                    {
                        item.Validacion = "Muestra no registrado.";
                        valida = false;
                    }
                }

                if (item.CodigoMuestraSondaje.Contains(Constantes.TipoSerieCodigoMuestra.CANAL))
                {
                    valida = true;

                    //Muestra de Canal
                    var muestra = muestrasCanales.Where(x => x.CodigoMuestraCanal == item.CodigoMuestraSondaje).FirstOrDefault();
                    if (muestra != null)
                    {
                        var canal = new DACanal().ObtenerCanal(muestra.CodigoCanal);
                        if (canal == null)
                        {
                            item.Validacion = "Canal no encontrado.";
                            valida = false;
                        }
                        else
                        {
                            if (canal.Estado == 2)
                            {
                                item.Validacion = "Canal con estado finalizado.";
                                valida = false;
                            }
                            else
                            {
                                #region Validacion margen de error
                                //Valida los rangos de error permitidos
                                if (!string.IsNullOrEmpty(muestra.CodigoMuestraCanalDuplicado))
                                {
                                    if (muestra.CodigoTipoControlCalidad == 2) //Tipo 2=Duplicada: No es necesario validar
                                    {
                                        var tipoControlCalidad = new DATipoControlCalidad().ObtenerTipoControlCalidad(muestra.CodigoTipoControlCalidad);
                                        var muestraAnterior = new DAMuestraSondaje().ObtenerMuestraSondaje(muestra.CodigoMuestraCanalDuplicado);

                                        //Compara con la muestra actual
                                        if (item.ValorAg > muestraAnterior.ValorAg + tipoControlCalidad.ErrorPermitidoAg)
                                        {
                                            item.Validacion = item.Validacion + " El ValorAg excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorCu > muestraAnterior.ValorCu + tipoControlCalidad.ErrorPermitidoCu)
                                        {
                                            item.Validacion = item.Validacion + " El ValorCu excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorPb > muestraAnterior.ValorPb + tipoControlCalidad.ErrorPermitidoPb)
                                        {
                                            item.Validacion = item.Validacion + " El ValorPb excede al margen de error establecido.";
                                            valida = false;
                                        }

                                        if (item.ValorZn > muestraAnterior.ValorZn + tipoControlCalidad.ErrorPermitidoZn)
                                        {
                                            item.Validacion = item.Validacion + " El ValorZn excede al margen de error establecido.";
                                            valida = false;
                                        }
                                    }
                                }
                                #endregion
                            }
                        }

                    }
                    else
                    {
                        item.Validacion = "Muestra canal no registrado.";
                        valida = false;
                    }
                }

                if (item.CodigoMuestraSondaje.Contains(Constantes.TipoSerieCodigoMuestra.ESPECIAL))
                {
                    valida = true;
                    //Muestra Especial
                    var muestra = muestrasEspeciales.Where(x => x.CodigoMuestraEspecial == item.CodigoMuestraSondaje).FirstOrDefault();
                    if (muestra != null)
                    {
                        #region Validacion margen de error
                        //Valida los rangos de error permitidos
                        if (!string.IsNullOrEmpty(muestra.CodigoMuestraEspecialDuplicado))
                        {
                            if (muestra.CodigoTipoControlCalidad == 2) //Tipo 2=Duplicada: No es necesario validar
                            {
                                var tipoControlCalidad = new DATipoControlCalidad().ObtenerTipoControlCalidad(muestra.CodigoTipoControlCalidad);
                                var muestraAnterior = new DAMuestraSondaje().ObtenerMuestraSondaje(muestra.CodigoMuestraEspecialDuplicado);

                                //Compara con la muestra actual
                                if (item.ValorAg > muestraAnterior.ValorAg + tipoControlCalidad.ErrorPermitidoAg)
                                {
                                    item.Validacion = item.Validacion + " El ValorAg excede al margen de error establecido.";
                                    valida = false;
                                }

                                if (item.ValorCu > muestraAnterior.ValorCu + tipoControlCalidad.ErrorPermitidoCu)
                                {
                                    item.Validacion = item.Validacion + " El ValorCu excede al margen de error establecido.";
                                    valida = false;
                                }

                                if (item.ValorPb > muestraAnterior.ValorPb + tipoControlCalidad.ErrorPermitidoPb)
                                {
                                    item.Validacion = item.Validacion + " El ValorPb excede al margen de error establecido.";
                                    valida = false;
                                }

                                if (item.ValorZn > muestraAnterior.ValorZn + tipoControlCalidad.ErrorPermitidoZn)
                                {
                                    item.Validacion = item.Validacion + " El ValorZn excede al margen de error establecido.";
                                    valida = false;
                                }
                            }
                        }
                        #endregion
                    }
                    else
                    {
                        item.Validacion = "Muestra especial no registrado.";
                        valida = false;
                    }
                }

                if (valida)
                {
                    item.Validacion = "Correcto";
                }
                //Siguiente
            }
            return leymuestras;
        }

        /// <summary>
        /// Método que actualiza las leyes muestra
        /// </summary>
        /// <param name="leymuestra"></param>
        public void ActualizarLeyMuestra(List<MuestraSondaje> leymuestras)
        {
            var damuestraCanal = new DAMuestraCanal();
            var damuestraEspecial = new DAMuestraEspecial();

            using (TransactionScope transaccion = new TransactionScope())
            {
                foreach (var item in leymuestras)
                {
                    if (item.CodigoMuestraSondaje.Contains("D") || item.CodigoMuestraSondaje.Contains("T")) //Muestra sondaje y taladro
                    {
                        var leymuestraEdit = Accesor.ObtenerMuestraSondaje(item.CodigoMuestraSondaje);
                        if (leymuestraEdit != null)
                        {
                            leymuestraEdit.ValorAg = item.ValorAg;
                            leymuestraEdit.ValorCu = item.ValorCu;
                            leymuestraEdit.ValorFe = item.ValorFe;
                            leymuestraEdit.ValorPb = item.ValorPb;
                            leymuestraEdit.ValorZn = item.ValorZn;
                            leymuestraEdit.ObservacionLey = item.ObservacionLey;
                            Accesor.ActualizarLeyMuestra(leymuestraEdit);
                        }
                    }
                    if (item.CodigoMuestraSondaje.Contains("C")) //Muestra de canal
                    {
                        var leymuestraEdit = damuestraCanal.ObtenerMuestraCanal(item.CodigoMuestraSondaje);
                        if (leymuestraEdit != null)
                        {
                            leymuestraEdit.ValorAg = item.ValorAg;
                            leymuestraEdit.ValorCu = item.ValorCu;
                            leymuestraEdit.ValorFe = item.ValorFe;
                            leymuestraEdit.ValorPb = item.ValorPb;
                            leymuestraEdit.ValorZn = item.ValorZn;
                            leymuestraEdit.ObservacionLey = item.ObservacionLey;
                            damuestraCanal.ModificarMuestraCanal(leymuestraEdit);
                        }
                    }
                    if (item.CodigoMuestraSondaje.Contains("E")) //Muestra Especial
                    {
                        var leymuestraEdit = damuestraEspecial.ObtenerMuestraEspecial(item.CodigoMuestraSondaje);
                        if (leymuestraEdit != null)
                        {
                            leymuestraEdit.ValorAg = item.ValorAg;
                            leymuestraEdit.ValorCu = item.ValorCu;
                            leymuestraEdit.ValorFe = item.ValorFe;
                            leymuestraEdit.ValorPb = item.ValorPb;
                            leymuestraEdit.ValorZn = item.ValorZn;
                            leymuestraEdit.ObservacionLey = item.ObservacionLey;
                            damuestraEspecial.ModificarMuestraEspecial(leymuestraEdit);
                        }
                    }
                }
                transaccion.Complete();
            }
        }

        /// <summary>
        /// Método busca muestra sondaje por nombre
        /// </summary>
        /// <param name="nombre"></param>
        /// <returns></returns>
        public List<MuestraSondajeResponse> BuscarMuestraSondaje(string nombre)
        {
            return Accesor.BuscarMuestraSondaje(nombre);
        }

        /// <summary>
        /// Método que devuelve una muestra de sondaje por código
        /// </summary>
        /// <param name="codigoMuestraSondaje"></param>
        /// <returns></returns>
        public MuestraSondaje ObtenerMuestraSondaje(string codigoMuestraSondaje)
        {
            return Accesor.ObtenerMuestraSondaje(codigoMuestraSondaje);
        }

        /// <summary>
        /// Devuelve el ultimo Hasta
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <returns></returns>
        public double ObtenerUltimoHasta(int codigoSondaje)
        {
            return Accesor.ObtenerUltimoHasta(codigoSondaje);
        }

        #endregion
        #region Utilidades
        /// <summary>
        /// Método que genera codigo tipo control calidad
        /// </summary>
        /// <returns></returns>
        public string GenerarCodigoMuestraSondaje()
        {
            return Accesor.GenerarCodigoMuestraSondaje();
        }

        /// <summary>
        /// Devuelve lista de Muestras por Sondaje
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <returns></returns>
        public List<buscarMuestraSondaje_Result> BuscarMuestraSondaje(int codigoSondaje)
        {
            return Accesor.BuscarMuestraSondaje(codigoSondaje);
        }

        /// <summary>
        /// Devuelve la lista para ComboBox, DropdownList, devuelve campos Value y Text
        /// </summary>
        /// <returns></returns>
        public List<ListItemString> ObtenerListItem(int codigoSondaje)
        {

            var result = Accesor.ListarMuestraSondaje(codigoSondaje);
            return result
                .Select(x => new ListItemString { Value = x.CodigoMuestraSondaje, Text = x.CodigoMuestraSondaje }).ToList();

        }
        /// <summary>
        /// Método devuelve lista muestra sondaje por codigo de sondaje y tipo de calidad
        /// </summary>
        /// <returns></returns>
        public List<MuestraSondaje> ListarMuestraSondajePorSondajeYTipoControlCalidad(int codigoSondaje, int codigoTipoControlCalidad)
        {
            return Accesor.ListarMuestraSondajePorSondajeYTipoControlCalidad(codigoSondaje, codigoTipoControlCalidad);
        }
        /// <summary>
        /// Devuelve la lista para ComboBox, DropdownList, devuelve campos Value y Text
        /// </summary>
        /// <returns></returns>
        public List<ListItemString> ObtenerListItem1(int codigoSondaje, int codigoTipoControlCalidad)
        {

            var result = Accesor.ListarMuestraSondajePorSondajeYTipoControlCalidad(codigoSondaje, codigoTipoControlCalidad);
            return result
                .Select(x => new ListItemString { Value = x.CodigoMuestraSondaje, Text = x.CodigoMuestraSondaje }).ToList();

        }
        /// <summary>
        /// Validar Interseccion
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <param name="tipoAnalisis"></param>
        /// <param name="desde"></param>
        /// <param name="hasta"></param>
        /// <returns></returns>
        public int ValidarInterseccionMuestraSondaje(int codigoSondaje, string codigoMuestraSondaje, double desde, double hasta, int codigoTipoControlCalidad)
        {
            return Accesor.ValidarInterseccionMuestraSondaje(codigoSondaje, codigoMuestraSondaje, desde, hasta, codigoTipoControlCalidad);
        }
        /// <summary>
        /// Devuelve 0 = Exito, 1 = No es valida la distancia
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <param name="hasta"></param>
        /// <param name="codigoTipoControlCalidad"></param>
        /// <returns></returns>
        public int ValidarDistanciaMuestraSondaje(int codigoSondaje, double hasta, int codigoTipoControlCalidad)
        {
            return Accesor.ValidarDistanciaMuestraSondaje(codigoSondaje, hasta, codigoTipoControlCalidad);
        }
        #endregion
        #region Accesor
        private static DAMuestraSondaje Accesor
        {
            [System.Diagnostics.DebuggerStepThrough]
            get { return new DAMuestraSondaje(); }
        }
        #endregion
    }
}
